home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Computer Select (Limited Edition)
/
Computer Select.iso
/
pcmag
/
v11n07
/
bachtocc.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-01-02
|
6KB
|
165 lines
/*---------------------------------------------------
BACHTOCC.C -- Bach Toccata in D Minor (First Bar)
(c) Charles Petzold, 1992
---------------------------------------------------*/
#include <windows.h>
#include <mmsystem.h>
#define ID_TIMER 1
long FAR PASCAL WndProc (HWND, WORD, WORD, LONG) ;
char szAppName[] = "BachTocc" ;
int PASCAL WinMain (HANDLE hInstance, HANDLE hPrevInstance,
LPSTR lpszCmdParam, int nCmdShow)
{
HWND hwnd ;
MSG msg ;
WNDCLASS wndclass ;
if (!hPrevInstance)
{
wndclass.style = CS_HREDRAW | CS_VREDRAW ;
wndclass.lpfnWndProc = WndProc ;
wndclass.cbClsExtra = 0 ;
wndclass.cbWndExtra = 0 ;
wndclass.hInstance = hInstance ;
wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION) ;
wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ;
wndclass.hbrBackground = GetStockObject (WHITE_BRUSH) ;
wndclass.lpszMenuName = NULL ;
wndclass.lpszClassName = szAppName ;
RegisterClass (&wndclass) ;
}
hwnd = CreateWindow (szAppName, "Bach Toccata in D Minor (First Bar)",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT,
NULL, NULL, hInstance, NULL) ;
ShowWindow (hwnd, nCmdShow) ;
UpdateWindow (hwnd) ;
while (GetMessage (&msg, NULL, 0, 0))
{
TranslateMessage (&msg) ;
DispatchMessage (&msg) ;
}
return msg.wParam ;
}
DWORD MidiOutMessage (HMIDIOUT hMidi, int iStatus, int iChannel,
int iData1, int iData2)
{
DWORD dwMessage ;
dwMessage = iStatus | iChannel | (iData1 << 8) | ((long) iData2 << 16) ;
return midiOutShortMsg (hMidi, dwMessage) ;
}
long FAR PASCAL WndProc (HWND hwnd, WORD message, WORD wParam, LONG lParam)
{
static struct
{
int iDur ;
int iNote [2] ;
}
noteseq [] = {
110, 69, 81, 110, 67, 79, 990, 69, 81, 220, -1, -1,
110, 67, 79, 110, 65, 77, 110, 64, 76, 110, 62, 74,
220, 61, 73, 440, 62, 74, 1980, -1, -1, 110, 57, 69,
110, 55, 67, 990, 57, 69, 220, -1, -1, 220, 52, 64,
220, 53, 65, 220, 49, 61, 440, 50, 62, 1980, -1, -1
} ;
static HMIDIOUT hMidiOut ;
static int iIndex ;
int i ;
switch (message)
{
case WM_CREATE:
if (!SetTimer (hwnd, ID_TIMER, 1000, NULL))
{
MessageBeep (MB_ICONEXCLAMATION) ;
MessageBox (hwnd, "Too many clocks or timers!",
szAppName, MB_ICONEXCLAMATION | MB_OK) ;
DestroyWindow (hwnd) ;
return 0 ;
}
if (midiOutOpen (&hMidiOut, MIDIMAPPER, NULL, NULL, 0L))
{
KillTimer (hwnd, ID_TIMER) ;
MessageBeep (MB_ICONEXCLAMATION) ;
MessageBox (hwnd, "Cannot open MIDI output device!",
szAppName, MB_ICONEXCLAMATION | MB_OK) ;
DestroyWindow (hwnd) ;
return 0 ;
}
// Send Program Change messages for "Church Organ"
MidiOutMessage (hMidiOut, 0xC0, 0, 19, 0) ;
MidiOutMessage (hMidiOut, 0xC0, 12, 19, 0) ;
return 0 ;
case WM_TIMER:
// Loop for 2-note polyphony
for (i = 0 ; i < 2 ; i++)
{
// Note Off messages for previous note
if (iIndex != 0 && noteseq[iIndex - 1].iNote[i] != -1)
{
MidiOutMessage (hMidiOut, 0x80, 0,
noteseq[iIndex - 1].iNote[i], 0) ;
MidiOutMessage (hMidiOut, 0x80, 12,
noteseq[iIndex - 1].iNote[i], 0) ;
}
// Note On messages for new note
if (iIndex != sizeof (noteseq) / sizeof (noteseq[0]) &&
noteseq[iIndex].iNote[i] != -1)
{
MidiOutMessage (hMidiOut, 0x90, 0,
noteseq[iIndex].iNote[i], 127) ;
MidiOutMessage (hMidiOut, 0x90, 12,
noteseq[iIndex].iNote[i], 127) ;
}
}
if (iIndex != sizeof (noteseq) / sizeof (noteseq[0]))
{
SetTimer (hwnd, ID_TIMER, noteseq[iIndex++].iDur - 1, NULL);
}
else
{
midiOutClose (hMidiOut) ;
KillTimer (hwnd, ID_TIMER) ;
DestroyWindow (hwnd) ;
}
return 0 ;
case WM_DESTROY:
PostQuitMessage (0) ;
return 0 ;
}
return DefWindowProc (hwnd, message, wParam, lParam) ;
}